﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Text.RegularExpressions;
using System.Data;
using TauschFormat2.Properties;
using Microsoft.Win32;
using System.IO;
using System.Runtime.InteropServices;

namespace TauschFormat2
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        #region variablendefinitionen
        StylesDBDataSet styleData = new StylesDBDataSet();
        PokeDataDataSet pkData = new PokeDataDataSet();
        StylesDBDataSetTableAdapters.StylesTableAdapter stylesDBTableAdapter = new StylesDBDataSetTableAdapters.StylesTableAdapter();
        PokeDataDataSetTableAdapters.AttackenTableAdapter pkAttackenAdapter = new PokeDataDataSetTableAdapters.AttackenTableAdapter();
        PokeDataDataSetTableAdapters.PokemonTableAdapter pkPokeAdapter = new PokeDataDataSetTableAdapters.PokemonTableAdapter();
        PokeDataDataSetTableAdapters.ItemsTableAdapter pkItemAdapter = new PokeDataDataSetTableAdapters.ItemsTableAdapter();
        PokeDataDataSetTableAdapters.FaehigkeitenTableAdapter pkFaehigkeitenAdapter = new PokeDataDataSetTableAdapters.FaehigkeitenTableAdapter();
        PokeDataDataSetTableAdapters.WesenTableAdapter pkWesenAdapter = new PokeDataDataSetTableAdapters.WesenTableAdapter();
        bool mehralseins = false;
        #endregion
        public MainWindow()
        {
            if (Environment.CurrentDirectory.Contains("Program Files") || Environment.CurrentDirectory.Contains("Programme"))
            {
                string connstring = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\Tauschformat\\Data";
                AppDomain.CurrentDomain.SetData("DataDirectory", connstring);
            }
            else
            {
                AppDomain.CurrentDomain.SetData("DataDirectory", Environment.CurrentDirectory + "\\Data");
            }
            InitializeComponent();
            //this.Loaded += (s, e) => { GlassEffectHelper.EnableGlassEffect(this); };
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            DisableClickSounds();
            LoadDataFromTables();
        }

        private void rbbttnSetPokemon_Click(object sender, RoutedEventArgs e)
        {
            PokemonEdit pkEdit = new PokemonEdit();
            pkEdit.ShowDialog();
            LoadDataFromTables();

        }
        private void LoadDataFromTables()
        {
            
            stylesDBTableAdapter.Fill(styleData.Styles);
            pkAttackenAdapter.Fill(pkData.Attacken);            
            pkPokeAdapter.Fill(pkData.Pokemon);            
            pkItemAdapter.Fill(pkData.Items);            
            pkFaehigkeitenAdapter.Fill(pkData.Faehigkeiten);            
            pkWesenAdapter.Fill(pkData.Wesen);

            var att = from r in pkData.Attacken select r.Attackenname;
            cbAttacke1.ItemsSource = att;
            cbAttacke2.ItemsSource = att;
            cbAttacke3.ItemsSource = att;
            cbAttacke4.ItemsSource = att;

            var pokes = from r in pkData.Pokemon select r.Pokemonname;
            cbPokemon.DataContext = pokes;

            var items = from r in pkData.Items select r.itemname;
            cbItems.ItemsSource = items;

            var wesen = from r in pkData.Wesen select r.Wesenname;
            cbWesen.ItemsSource = wesen;

            var faehigkeiten = from r in pkData.Faehigkeiten select r.Faehigkeit;
            cbFaehigkeit.ItemsSource = faehigkeiten;

            var styles = from r in styleData.Styles select r.name;
            rbcbDeginauswahl.Items.Clear();
            foreach (string style in styles)
            {
                TextBlock block = new TextBlock();
                block.Text = style;
                rbcbDeginauswahl.Items.Add(block);
            }
            rbcbDeginauswahl.SelectedIndex = 0;
            
        }

        private void Window_Initialized(object sender, EventArgs e)
        {
            
        }

        private void rbbttnSetItems_Click(object sender, RoutedEventArgs e)
        {
            ItemEdit iEdit = new ItemEdit();
            iEdit.ShowDialog();
            LoadDataFromTables();
        }

        private void rbbttnSetMoves_Click(object sender, RoutedEventArgs e)
        {
            Attacken aEdit = new Attacken();
            aEdit.ShowDialog();
            LoadDataFromTables();
        }

        private void rbbttnSetStyles_Click(object sender, RoutedEventArgs e)
        {
            Styles styles = new Styles();
            styles.ShowDialog();
            LoadDataFromTables();
        }

        private void RibbonButton_Click(object sender, RoutedEventArgs e)
        {
            if (mehralseins)
            {
                if (MessageBox.Show("Die letzte Ausgabe war eine Mehrfachausgabe. \r\nBeim Fortfahren wird sämtlicher bereits ausgegebener Code im Ausgabefeld gelöscht.\r\nFortfahren?", "", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
                {
                    return;
                }
            }
            txtAusgabe.Text = GenerateCode(true);
            mehralseins = false;
            expAusgabe.IsExpanded = true;
        }

        private string GenerateCode(bool ausgabe)
        {
            string[] statarray = new string[] {"KP","Angr","Vert","SpzAngr","SpzVert","Init"};
            string ret = "";
            string temps = "";
            var t = from r in styleData.Styles where r.name == rbcbDeginauswahl.Text select r.style;

            foreach (var style in t)
            {
                ret = style;
                int temp = cbPokemon.SelectedIndex+1;
                temps = temp.ToString();
                if (temp < 100 && temp < 10)
                {
                    temps = "00" + temp.ToString();
                }
                if (temp < 100 && temp > 9)
                {
                    temps = "0" + temp.ToString();
                }
                //Sprite
                if (chbShiny.IsChecked == true)
                {
                    //Es ist ein Shiny. Ueberschreiben der Einstellung....
                    ret = Regex.Replace(ret, "{Sprite=(.+)}", "[sprite=shiny]" + temps + "[/sprite]");
                }
                else
                {
                    //Kein Shiny. Code-Einstellung verwenden.
                    ret = Regex.Replace(ret, "{Sprite=(.+)}", "[sprite=$1]" + temps + "[/sprite]");
                    ret = ret.Replace("{Sprite}", "[sprite]" + temps + "[/sprite]");
                }
                // Pokemon
                ret = ret.Replace("{Pokemon}", cbPokemon.SelectedItem.ToString());
                // Geschlecht
                if (rbWeiblich.IsChecked.Value)
                    ret = ret.Replace("{Geschlecht}", "[img]http://pokefans.net/images/geschlecht_w.gif[/img]");
                else
                    if (rbMaennlich.IsChecked.Value)
                        ret = ret.Replace("{Geschlecht}", "[img]http://pokefans.net/images/geschlecht_m.gif[/img]");
                    else
                        ret = ret.Replace("{Geschlecht}", "");
                // OT
                ret = ret.Replace("{OT}", txtOriginaltrainer.Text);
                // Trainer ID
                ret = ret.Replace("{TrainerID}", txtTID.Text);
                // Level
                ret = ret.Replace("{Level}", udLevel.Value.ToString());
                #region wesen
                if (cbWesen.SelectedItem != null)
                {
                    // Wesen
                    ret = ret.Replace("{Wesen}", cbWesen.SelectedItem.ToString());
                }
                else
                {
                    ret = ret.Replace("{Wesen}", "");
                }
                #endregion
                #region faehigkeit
                if(cbFaehigkeit.SelectedItem != null)
                {
                    // Faehigkeit
                    ret = ret.Replace("{Faehigkeit}", cbFaehigkeit.SelectedItem.ToString());
                }
                else
                {
                    ret = ret.Replace("{Faehigkeit}", "");
                }
                #endregion
                #region item
                if(cbItems.SelectedItem != null)
                {
                    // Item
                    ret = ret.Replace("{Item}", cbItems.SelectedItem.ToString());
                }
                else
                {
                    ret = ret.Replace("{Item}", "");
                }
                #endregion
                // EVs
                ret = ret.Replace("{EV}", buildEVString(false));
                // EVs mit UT-Hinweis
                ret = ret.Replace("{EV2}", buildEVString(true));
                // DVs
                ret = ret.Replace("{DV}", buildDVString());
                #region attacken
                if(cbAttacke1.SelectedItem != null)
                {
                    // Attacken
                    ret = ret.Replace("{Attacke1}",proofHP(cbAttacke1.SelectedItem.ToString()));
                }
                else
                {
                    ret = ret.Replace("{Attacke1}", "");
                }
                
                if(cbAttacke2.SelectedItem != null)
                {
                    ret = ret.Replace("{Attacke2}", proofHP(cbAttacke2.SelectedItem.ToString()));
                }
                else
                {
                    ret = ret.Replace("{Attacke2}", "");
                }

                if(cbAttacke3.SelectedItem != null)
                {
                    ret = ret.Replace("{Attacke3}", proofHP(cbAttacke3.SelectedItem.ToString()));
                }
                else
                {
                    ret = ret.Replace("{Attacke3}", "");
                }

                if(cbAttacke4.SelectedItem != null)
                {
                    ret = ret.Replace("{Attacke4}", proofHP(cbAttacke4.SelectedItem.ToString()));
                }
                else
                {
                    ret = ret.Replace("{Attacke4}", "");
                }
#endregion
                //Kommentar
                ret = ret.Replace("{Kommentar}", txtKommentar.Text);
                ret = ret.Replace("<br /><td>", "<td>");
                if (ausgabe)
                {
                    ret = ret.Replace("]\n[", "][");
                    ret = ret.Replace("]\r[", "][");
                    ret = ret.Replace("]\r\n[", "][");
                }
            }
            return ret;
        }

        private string buildEVString(bool promode)
        {
            StringBuilder Output = new StringBuilder();
            if (chbEVUnbekannt.IsChecked == true)
            {
                if (promode)
                    Output.Append("UT");
                else
                    Output.Append("Unbekannt oder Uninteressant");
            }
            else
            {
                
                bool first = true;
                if (int.Parse(udEVKP.Value.ToString()) != 0)
                {
                    Output.Append(" " + udEVKP.Value.ToString() + " KP");
                    first = false;
                }
                if (int.Parse(udEVAngr.Value.ToString()) != 0)
                {
                    if (first)
                    {
                        Output.Append(" " + udEVAngr.Value.ToString() + " Angr");
                        first = false;
                    }
                    else
                    {
                        Output.Append(" | " + udEVAngr.Value.ToString() + " Angr");
                    }
                }
                if (int.Parse(udEVVert.Value.ToString()) != 0)
                {
                    if (first)
                    {
                        Output.Append(" " + udEVVert.Value.ToString() + " Vert");
                        first = false;
                    }
                    else
                    {
                        Output.Append(" | " + udEVVert.Value.ToString() + " Vert");
                    }
                }
                if (int.Parse(udEVInit.Value.ToString()) != 0)
                {
                    if (first)
                    {
                        Output.Append(" " + udEVInit.Value.ToString() + " Init");
                        first = false;
                    }
                    else
                    {
                        Output.Append(" | " + udEVInit.Value.ToString() + " Init");
                    }
                }
                if (int.Parse(udEVSpAngr.Value.ToString()) != 0)
                {
                    if (first)
                    {
                        Output.Append(" " + udEVSpAngr.Value.ToString() + " SpAngr");
                        first = false;
                    }
                    else
                    {
                        Output.Append(" | " + udEVSpAngr.Value.ToString() + " SpAngr");
                    }
                }
                if (int.Parse(udEVSpVert.Value.ToString()) != 0)
                {
                    if (first)
                    {
                        Output.Append(" " + udEVSpVert.Value.ToString() + " SpVert");
                        first = false;
                    }
                    else
                    {
                        Output.Append(" | " + udEVSpVert.Value.ToString() + " SpVert");
                    }
                }
            }

            return Output.ToString();
        }
        #region DV zeug
        private string buildDVString()
        {
            if (chbDVUnbekannt.IsChecked == false)
                return checkDV(int.Parse(udDVKP.Value.ToString())) + "|" + checkDV(int.Parse(udDVAngr.Value.ToString())) + "|" + checkDV(int.Parse(udDVVert.Value.ToString())) + "|" + checkDV(int.Parse(udDVSpAngr.Value.ToString())) + "|" + checkDV(int.Parse(udDVSpVert.Value.ToString())) + "|" + checkDV(int.Parse(udDVInit.Value.ToString()));
            else
                return "Unbekannt oder Uninterssant";
        }
        private string checkDV(int dv)
        {
            if (dv >= 30)
                return "[b]" + dv.ToString() + "[/b]";
            if (dv >= 27 && dv <= 29)
                return "[u]" + dv.ToString() + "[/u]";
            if (dv < 27)
                return dv.ToString();
            return "Fehler";
        }
        #endregion
        private string proofHP(string Attname)
        {
            StringBuilder Output = new StringBuilder();
            Settings set = new Settings();
            if (Attname == set.Kraftreservename)
            {
                //Calculate Type and Strength, Only if DVs are filled in
                if (!chbDVUnbekannt.IsChecked.Value)
                {
                    Output.Append("[attacke]" + Attname + "[/attacke] {");
                    string[] typ = new string[16];
                    typ[0] = "Kampf";
                    typ[1] = "Flug";
                    typ[2] = "Gift";
                    typ[3] = "Boden";
                    typ[4] = "Gestein";
                    typ[5] = "Käfer";
                    typ[6] = "Geist";
                    typ[7] = "Stahl";
                    typ[8] = "Feuer";
                    typ[9] = "Wasser";
                    typ[10] = "Pflanze";
                    typ[11] = "Elektro";
                    typ[12] = "Psycho";
                    typ[13] = "Eis";
                    typ[14] = "Drache";
                    typ[15] = "Unlicht";
                    int a, b, c, d, ee, f;
                    if (int.Parse(udDVKP.Value.ToString()) % 2 == 0)
                        a = 0;
                    else
                        a = 1;
                    if (int.Parse(udDVAngr.Value.ToString()) % 2 == 0)
                        b = 0;
                    else
                        b = 2;
                    if (int.Parse(udDVVert.Value.ToString()) % 2 == 0)
                        c = 0;
                    else
                        c = 4;
                    if (int.Parse(udDVInit.Value.ToString()) % 2 == 0)
                        d = 0;
                    else
                        d = 8;
                    if (int.Parse(udDVSpAngr.Value.ToString()) % 2 == 0)
                        ee = 0;
                    else
                        ee = 16;
                    if (int.Parse(udDVSpVert.Value.ToString()) % 2 == 0)
                        f = 0;
                    else
                        f = 32;
                    decimal type = ((decimal)a + (decimal)b + (decimal)c + (decimal)d + (decimal)ee + (decimal)f) * 15 / 63;
                    Output.Append(typ[(int)Math.Floor(type)] + "}");

                    decimal power = (Math.Floor((decimal.Parse(udDVKP.Value.ToString()) % 4) / 2) + Math.Floor((decimal.Parse(udDVAngr.Value.ToString()) % 4) / 2) * 2 + Math.Floor((decimal.Parse(udDVVert.Value.ToString()) % 4) / 2) * 4 + Math.Floor((decimal.Parse(udDVInit.Value.ToString()) % 4) / 2) * 8 + Math.Floor((decimal.Parse(udDVSpAngr.Value.ToString()) % 4) / 2) * 16 + Math.Floor((decimal.Parse(udDVSpVert.Value.ToString()) % 4) / 2) * 32) * 40 / 63 + 30;
                    Output.Append(" " + Math.Floor(power).ToString());
                    return Output.ToString();
                }
                else
                {
                    return "[attacke]" + Attname + "[/attacke]";
                }
            }
            else
            {
                return "[attacke]"+Attname+"[/attacke]";
            }
        }

        private void rbbttnSetWesen_Click(object sender, RoutedEventArgs e)
        {
            Wesen wEdit = new Wesen();
            wEdit.ShowDialog();
            LoadDataFromTables();
        }

        private void rbbttnSetFaehigkeit_Click(object sender, RoutedEventArgs e)
        {
            FaehigkeitenEdit fEdit = new FaehigkeitenEdit();
            fEdit.ShowDialog();
            LoadDataFromTables();
        }

        private void RibbonButton_Click_1(object sender, RoutedEventArgs e)
        {
            txtAusgabe.Text += GenerateCode(true);
            mehralseins = true;
            expAusgabe.IsExpanded = true;
        }

        private void buildPreview(object sender, TextChangedEventArgs e)
        {
            previewHelper();
        }

        private void buildPreview(object sender, SelectionChangedEventArgs e)
        {
            previewHelper();
        }

        private void buildPreview(object sender, RoutedEventArgs e)
        {
            previewHelper();
        }

        private void buildPreview(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            previewHelper();
        }
        private void previewHelper()
        {
            string preview = GenerateCode(false);
            Settings set = new Settings();
            BBCodeDataSet bbData = new BBCodeDataSet();
            try
            {
                BBCodeDataSetTableAdapters.BBCodesTableAdapter bbDataAdapter = new BBCodeDataSetTableAdapters.BBCodesTableAdapter();
                bbDataAdapter.Fill(bbData.BBCodes);
            }
            catch (Exception Ex)
            {
                MessageBox.Show(Ex.Message + "\r\n\r\n" + Ex.StackTrace, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                Application.Current.Shutdown();
            }

            foreach(DataRow r in bbData.BBCodes.Rows) 
            {
                try
                {
                    preview = Regex.Replace(preview, (string)r["expression"], (string)r["replace"], RegexOptions.Multiline);
                    preview = Regex.Replace(preview, (string)r["expression"], (string)r["replace"], RegexOptions.Singleline);
                }
                catch (Exception ex)
                {
                }
            }
            if (Regex.Match(preview, "<td>", RegexOptions.Singleline).Success && !Regex.Match(preview, "<table>", RegexOptions.Singleline).Success)
            {
                if (!Regex.Match(preview, "<tr(.+)>", RegexOptions.Singleline).Success)
                {
                    preview = "<tr class=\"tb_1\">" + preview + "</tr>";
                }
                preview = "<table class=\"tb\">" + preview + "</table>";
            }
            preview = preview.Replace("\r\n", "<br />");
            preview = preview.Replace("</td><br /><td>", "</td><td>");
            preview = set.HTMLBefore + preview + set.HTMLAfter;
            try
            {
                brwsrVorschau.NavigateToString(preview);
                brwsrVorschau.Opacity = 0;
            }
            catch(Exception ex)
            {
                
            }
        }

        private void rbbttnSetBBC_Click(object sender, RoutedEventArgs e)
        {
            BBCode bbEdit = new BBCode();
            bbEdit.ShowDialog();
        }

        private void mniSpeichernUnter_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "Text-Dateien (*.txt)|*.txt";
            Nullable<bool> result = sfd.ShowDialog();
            if (result == true)
            {
                StreamWriter wrtr = new StreamWriter(sfd.FileName);
                wrtr.Write(txtAusgabe.Text);
                wrtr.Close();
            }
        }
        #region disable click sound
        const int FEATURE_DISABLE_NAVIGATION_SOUNDS = 21;
        const int SET_FEATURE_ON_PROCESS = 0x00000002;

        [DllImport("urlmon.dll")]
        [PreserveSig]
        [return: MarshalAs(UnmanagedType.Error)]
        static extern int CoInternetSetFeatureEnabled(
            int FeatureEntry,
            [MarshalAs(UnmanagedType.U4)] int dwFlags,
            bool fEnable);

        static void DisableClickSounds()
        {
            CoInternetSetFeatureEnabled(
                FEATURE_DISABLE_NAVIGATION_SOUNDS,
                SET_FEATURE_ON_PROCESS,
                true);
        }
        #endregion
    }
}
